#include <algorithm>
#include <cstdio>
#include <queue>

const int N = 6005;
int n, m, k, sum[100010], dx[4] = {0, 0, -1, 1}, dy[4] = {1, -1, 0, 0};
char map[N][N];
bool vis[N][N];

struct Node {
  int x, y;
  Node(int x, int y) : x(x), y(y) {}
};

inline void solve(const int &i, const int &j) {
  ++k;
  std::queue<Node> q;
  q.push(Node(i, j));
  vis[i][j] = true;
  while (!q.empty()) {
    int x = q.front().x, y = q.front().y;
    q.pop();
    sum[k] += map[x][y];
    for (int h = 0, tx, ty; h < 4; ++h) {
      tx = x + dx[h], ty = y + dy[h];
      if (map[tx][ty] != 0 && tx > 0 && ty > 0 && tx <= n && ty <= m)
        if (!vis[tx][ty]) {
          vis[tx][ty] = true;
          q.push(Node(tx, ty));
        }
    }
  }
}

inline bool cmp(const int &lhs, const int &rhs) { return lhs > rhs; }

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("testdata.in", "r", stdin);
  freopen("testdata.out", "w", stdout);
#else
  freopen("coin.in", "r", stdin);
  freopen("coin.out", "w", stdout);
#endif
#endif

  scanf("%d%d", &m, &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%s", map[i] + 1);
    for (int j = 1; j <= m; ++j) { map[i][j] -= '0'; }
  }
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      if (!vis[i][j] && map[i][j] != 0) { solve(i, j); }
    }
  }
  printf("%d\n", k);
  std::sort(sum + 1, sum + k + 1, cmp);
  for (int i = 1; i <= k; ++i) { printf("%d ", sum[i]); }
  return 0;
}